<!--template  -->
<template>
    <div class='box'>
        <div class="equ-detail">
            <div class="detail">当前显示总数据 <span class="numberRun">1234</span></div>
        </div>
        <!-- <div id="container" style="width:100%;height:500px"> </div> -->
    </div>
</template>
<script >
import { toRefs, reactive, onMounted } from '@vue/composition-api'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
// import $ from 'jquery'
import  numberRunInit from '@/assets/js/numRun.js'
export default {
    setup(props, { root }) {
        const state = reactive({
            scene: null,
            camera: null,
            mesh: null,
            renderer: null,
            gltfLoader: null
        })

        onMounted(() => {
            init()
            animate()
            numberRunInit($)
        })


        function init() {

            // 1、创建场景
            state.scene = new THREE.Scene();
            // 2、创建网络模型
            // var geometry = new THREE.SphereGeometry(60,40,40) //几何球体对象
            var geometry = new THREE.BoxGeometry(100, 100, 100) //创建立方体几何对象
            // 3、为集合体设置材质
            var material = new THREE.MeshPhongMaterial({
                color: 0x0000ff,
                specular: "#FFF", //高光颜色
                shininess: 12, //光照强度系数
                // transparent:true,
                // opacity:0.7
            })
            state.mesh = new THREE.Mesh(geometry, material) //网络模型对象mesh
            // 4、网络模型添加到场景中
            // state.scene.add(state.mesh)  
            // 5、设置光源
            // 点光源
            var point = new THREE.DirectionalLight(0xffffff);
            point.position.set(400, 200, 300); //点光源位置
            state.scene.add(point)
            // 环境光
            var ambient = new THREE.AmbientLight();
            state.scene.add(ambient)

            getGLTF()
            console.log(state.scene);
            // 6、相机设置
            var width = window.innerWidth;
            var height = window.innerHeight;
            var k = width / height; //宽高比
            var s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
            // 创建相机（透视相机）
            state.camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);

            // var camera =new THREE.PerspectiveCamera(
            //     70,
            //     container.clientWidth / container.clientHeight,
            //     0.01,
            //     10
            // );
            state.camera.position.set(200, 300, 200);
            state.camera.lookAt(state.scene.position) //设置相机方向，指向场景


            // 7、渲染器对象
            state.renderer = new THREE.WebGLRenderer({ antialias: true });
            state.renderer.setSize(width, height)
            state.renderer.setClearColor("#000", 1); //设置背景色

            document.body.appendChild(state.renderer.domElement); //body元素中插入canvas对象

            // 8、事件控制变化
            var controls = new OrbitControls(state.camera, state.renderer.domElement);//创建监控对象(相机,dom)

            // 9、辅助坐标系  参数250表示坐标系大小，可以根据场景大小去设置
            // var AxesHelper = new THREE.AxesHelper(50);
            // state.scene.add(AxesHelper);


            setArrowHelper()
            addEventListener('dblclick', onMouseDblclick, false);
        }

        // 加载gltf格式文件
        function getGLTF() {
            state.gltfLoader = new GLTFLoader()
            state.gltfLoader.load('gltf/people-demo3.gltf', gltf => {
                debugger
                console.log(gltf);
                // 文件场景内容全部导入
                state.scene.add(gltf.scene)
            }, xhr => {
                // 模型加载期间的回调函数
                console.log(`${(xhr.loaded / xhr.total) * 100} building model loaded`)
            }, error => {
                console.log("error while loading", error);
            })
        }

        function animate() {
            requestAnimationFrame(animate)
            state.mesh.rotation.x += 0.01
            state.mesh.rotation.y += 0.02
            state.renderer.render(state.scene, state.camera)
        }

        // 获取点击射线相交对象
        function getIntersects(event, camera, scene) {
            event.preventDefault();
            debugger
            console.log("event.clientX:" + event.clientX)
            console.log("event.clientY:" + event.clientY)

            // 声明 raycaster 和 mouse 变量
            var raycaster = new THREE.Raycaster()
            var mouse = new THREE.Vector2()

            // 通过鼠标点击位置,计算出 raycaster 所需点的位置,以屏幕为中心点,范围 -1 到 1
            mouse.x = (event.clientX / window.innerWidth) * 2 - 1
            mouse.y = -(event.clientY / window.innerHeight) * 2 + 1

            //通过鼠标点击位置和相机的位置计算出射线位置
            raycaster.setFromCamera(mouse, camera)
            var intersects = []
            for (let i = 0; i < scene.children.length; i++) {
                const item = scene.children[i];
                if (item.type == 'Group') {
                    intersects = raycaster.intersectObjects(item.children)
                    break
                }
            }
            return intersects
        }

        // 鼠标双击触发的方法
        function onMouseDblclick(event) {
            // 获取 raycaster 和所有模型相交的数组，其中的元素按照距离排序，越近的越靠前
            var intersects = getIntersects(event, state.camera, state.scene);

            // 获取选中最近的 Mesh 对象
            if (intersects.length != 0 && intersects[0].object instanceof THREE.Mesh) {
                changeMaterial(intersects[0].object);
                renderDiv(intersects[0].object)
            } else {
                console.log("未选中 Mesh!");
                $(".equ-detail").css({
                    display: 'none'
                })
            }
        }

        // 改变对象材质属性
        function changeMaterial(object) {
            var material = new THREE.MeshLambertMaterial({
                color: 0xffffff * Math.random(),
                transparent: object.material.transparent ? false : true,
                opacity: 0.8
            });
            object.material = material;
        }

        function setArrowHelper() {
            //来自原点的方向。必须是单位向量
            var dir = new THREE.Vector3(0, 10, 0);
            var dir2 = new THREE.Vector3(10, 0, 0);
            var dir3 = new THREE.Vector3(0, 0, 10);

            // 规格化方向向量(转换为长度为1的向量)
            dir.normalize();

            // 箭头开始的点
            var origin = new THREE.Vector3(0, 0, 0);

            // 箭头的长度。默认值为1
            var length = 60;

            // 用于定义颜色的十六进制值。默认值为0xffff00
            var hex = '#fff';
            var hex = '#fff';
            var hex = '#fff';

            // 箭头的长度。默认值为0.2 *length
            var headLength = 10;

            // 箭头宽度的长度。默认值为0.2 * headLength。
            var headWidth = 2;

            var arrowHelper = new THREE.ArrowHelper(dir, origin, length, hex, headLength, headWidth);
            state.scene.add(arrowHelper)

            var arrowHelper2 = new THREE.ArrowHelper(dir2, origin, length, hex, headLength, headWidth);
            state.scene.add(arrowHelper2)

            var arrowHelper3 = new THREE.ArrowHelper(dir3, origin, length, hex, headLength, headWidth);
            state.scene.add(arrowHelper3)
        }

        function renderDiv(object) {
            // 获取窗口的一半高度和宽度
            var halfWidth = window.innerWidth / 2;
            var halfHeight = window.innerHeight / 2;

            // 逆转相机求出二维坐标
            var vector = object.position.clone().project(state.camera);

            // 修改 div 的位置
            $(".equ-detail").css({
                left: vector.x * halfWidth + halfWidth,
                top: -vector.y * halfHeight + halfHeight - object.position.y,
                display: 'block'
            });
            // 显示模型信息
            $(".numberRun").numberAnimate({ num: Math.random() * 100000, speed: 600 });

        }

        return {
            ...toRefs(state),
        };
    }
}

 </script>
 <style lang='scss' scoped>
.equ-detail {
    position: fixed;
    display: none;
    pointer-events: none;
    // display: none;
    width: 200px;
    height: 100px;
    border: 1px solid #3986ff;
    border-radius: 4px;
    text-align: center;
    z-index: 999;
    .num {
        // display: inline-block;
        // margin: 0 4px;
        // font-size: 28px;
    }
}
</style>